﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using System.Collections;
using System.Runtime.Serialization;

// hack Organize as a class extension instead of derived class
namespace UniBasel.Biozentrum.Utils
{
	[Serializable]
	public class OrderedDictionaryEx : OrderedDictionary
	{
		/// <summary>
		/// Switches the content of two entries with indexes i and j, respectively.
		/// </summary>
		/// <param name="i">Index of first entry.</param>
		/// <param name="j">Index of second entry</param>
		/// <exception cref="ArgumentOutOfRangeException">If i or j are greater than the actual number of elements in dictionary.</exception>
		public void SwitchTwo(int i, int j)
		{
			int Capacity = base.Count;
			if(i==j) return;
			if (i >= Capacity) throw new ArgumentOutOfRangeException("i", i, string.Format("The index is greater than the actual number of elements '{0}' in the dictionary.", Capacity));
			if (j >= Capacity) throw new ArgumentOutOfRangeException("j", j, string.Format("The index is greater than the actual number of elements '{0}' in the dictionary.", Capacity));
			int temp;
			if (i > j)
			{
				temp = i;
				i = j;
				j = temp;
			}

			object[] myKeys = new object[Capacity]; // Get an array of Keys
			base.Keys.CopyTo(myKeys, 0);
			object[] myValues = new object[Capacity];
			base.Values.CopyTo(myValues, 0);

			DictionaryEntry iEntry = new DictionaryEntry(myKeys[i], myValues[i]);
			DictionaryEntry jEntry = new DictionaryEntry(myKeys[j], myValues[j]);

			base.Remove(iEntry.Key);
			base.Remove(jEntry.Key);

			base.Insert(i, jEntry.Key, jEntry.Value);
			base.Insert(j, iEntry.Key, iEntry.Value);
		}

		/// <summary>
		/// Function to get the index of entry by its key.
		/// </summary>
		/// <param name="key"></param>
		/// <returns> Int Index if key found and -1 if not found.</returns>
		public int GetIndexOf(object key)
		{
			if (!base.Contains(key)) return -1; // If key is not in Dictionary - return -1

			int Capacity = base.Count;
			object[] myKeys = new object[Capacity]; // Get an array of Keys
			base.Keys.CopyTo(myKeys, 0);
			for (int i = 0; i < this.Count; i++)
			{
				if (myKeys[i].Equals(key)) return i;
			}
			return -1;
		}

		public OrderedDictionaryEx(SerializationInfo i, StreamingContext c)
			: base(i, c) // Essential for serialization
		{
 
		}
		
		public OrderedDictionaryEx():base()
		{
			// No new logic except for constructor
		}
	}
}